package com.zz.common.codeGenerator.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zz.common.base.dto.PageListResultDto;
import com.zz.common.base.enums.BaseExceptionEnum;
import com.zz.common.base.param.QueryParam;
import com.zz.common.codeGenerator.dto.GenTableColumnDto;
import com.zz.common.codeGenerator.entity.GenTableColumn;
import com.zz.common.codeGenerator.mapper.GenTableColumnMapper;
import com.zz.common.codeGenerator.service.GenTableColumnService;
import com.zz.common.constants.BaseConstant;
import com.zz.common.exception.ExceptionFactory;
import com.zz.common.utils.common.UUIDGenerator;
import com.zz.common.utils.mapper.BeanMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 代码生成业务表字段 服务实现类
 *
 * @author zhang.lei
 * @since 2025-08-18 20:32:36
 */
@Service
@Slf4j
public class GenTableColumnServiceImpl extends ServiceImpl<GenTableColumnMapper, GenTableColumn> implements GenTableColumnService {

    @Resource
    private GenTableColumnMapper genTableColumnMapper;

    @Override
    public PageListResultDto<GenTableColumnDto> queryWithPage(GenTableColumnDto genTableColumnDto, QueryParam queryParam) {
        Page<GenTableColumn> page = new Page<>(queryParam.getPageNum(), queryParam.getPageSize());
        QueryWrapper<GenTableColumn> wrapper = new QueryWrapper<>();
        wrapper.eq("del_flag", BaseConstant.NO);
        List<GenTableColumn> genTableColumns = genTableColumnMapper.selectList(page, wrapper);
        List<GenTableColumnDto> genTableColumnDtos = BeanMapper.mapList(genTableColumns, GenTableColumn.class, GenTableColumnDto.class);
        return new PageListResultDto<>((int) page.getCurrent(), (int) page.getTotal(), queryParam.getPageSize(), genTableColumnDtos);
    }

    @Override
    public List<GenTableColumnDto> queryWithNoPage(GenTableColumnDto genTableColumnDto) {
        QueryWrapper<GenTableColumn> wrapper = new QueryWrapper<>();
        wrapper.eq("del_flag", BaseConstant.NO);
        List<GenTableColumn> genTableColumns = genTableColumnMapper.selectList(wrapper);
        return BeanMapper.mapList(genTableColumns, GenTableColumn.class, GenTableColumnDto.class);
    }

    @Override
    public GenTableColumnDto queryById(String id) {
        if (StringUtils.isBlank(id)) {
            return null;
        }
        GenTableColumn genTableColumn = genTableColumnMapper.selectById(id);
        if (genTableColumn == null || BaseConstant.YES.equals(genTableColumn.getDelFlag())) {
            return null;
        }
        return BeanMapper.map(genTableColumn, GenTableColumnDto.class);
    }

    @Override
    public List<GenTableColumnDto> queryByIds(List<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return new ArrayList<>();
        }
        List<GenTableColumn> genTableColumns = genTableColumnMapper.selectByIds(ids);
        if (CollectionUtils.isEmpty(genTableColumns)) {
            return new ArrayList<>();
        }
        return BeanMapper.mapList(genTableColumns, GenTableColumn.class, GenTableColumnDto.class);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public GenTableColumnDto save(GenTableColumnDto genTableColumnDto) {
        // 根据业务修改
        return insert(genTableColumnDto);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<GenTableColumnDto> saveBatch(List<GenTableColumnDto> genTableColumnDtos) {
        // 根据业务修改
        return insertList(genTableColumnDtos);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public GenTableColumnDto modify(GenTableColumnDto genTableColumnDto) {
        // 根据业务修改
        updateById(genTableColumnDto);
        return genTableColumnDto;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<GenTableColumnDto> modifyBatch(List<GenTableColumnDto> genTableColumnDtos) {
        // 对数组中的某些字段执行简单赋值逻辑
        for (GenTableColumnDto column : genTableColumnDtos) {
            if (StringUtils.isBlank(column.getIsPk())) column.setIsPk(BaseConstant.NO);
            if (StringUtils.isBlank(column.getIsInsert())) column.setIsInsert(BaseConstant.NO);
            if (StringUtils.isBlank(column.getIsEdit())) column.setIsEdit(BaseConstant.NO);
            if (StringUtils.isBlank(column.getIsList())) column.setIsList(BaseConstant.NO);
            if (StringUtils.isBlank(column.getIsRequired())) column.setIsRequired(BaseConstant.NO);
            if (StringUtils.isBlank(column.getIsQuery())) column.setIsQuery(BaseConstant.NO);
            if (StringUtils.isBlank(column.getIsLink())) column.setIsLink(BaseConstant.NO);
            if (StringUtils.isBlank(column.getIsIncrement())) column.setIsIncrement(BaseConstant.NO);
        }

        return updateList(genTableColumnDtos);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(String id) {
        // 根据业务修改
        GenTableColumnDto genTableColumnDto = new GenTableColumnDto();
        genTableColumnDto.setColumnId(id);
        deleteById(genTableColumnDto);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteBatch(List<String> ids) {
        // 根据业务修改
        deleteByPrimaryKeys(ids);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public GenTableColumnDto insert(GenTableColumnDto genTableColumnDto) {
        genTableColumnDto.setColumnId(UUIDGenerator.generateUUID());
        genTableColumnDto.setDelFlag(BaseConstant.NO);
        GenTableColumn entity = BeanMapper.map(genTableColumnDto, GenTableColumn.class);
        genTableColumnMapper.insert(entity);
        return genTableColumnDto;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public GenTableColumnDto insertWithId(GenTableColumnDto genTableColumnDto) {
        if (StringUtils.isBlank(genTableColumnDto.getColumnId())) {
            genTableColumnDto.setColumnId(UUIDGenerator.generateUUID());
        }
        genTableColumnDto.setDelFlag(BaseConstant.NO);
        GenTableColumn entity = BeanMapper.map(genTableColumnDto, GenTableColumn.class);
        genTableColumnMapper.insert(entity);
        return genTableColumnDto;
    }

    private List<GenTableColumnDto> insertList(List<GenTableColumnDto> genTableColumnDtos) {
        if (CollectionUtils.isEmpty(genTableColumnDtos)) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.INTERNAL_SERVER_ERROR, "批量插入时，参数不能为空");
        }
        List<GenTableColumn> insertList = new ArrayList<>();
        for (GenTableColumnDto genTableColumnDto : genTableColumnDtos) {
            if (StringUtils.isBlank(genTableColumnDto.getColumnId())) {
                genTableColumnDto.setColumnId(UUIDGenerator.generateUUID());
            }
            genTableColumnDto.setDelFlag(BaseConstant.NO);
            insertList.add(BeanMapper.map(genTableColumnDto, GenTableColumn.class));
        }
        genTableColumnMapper.insert(insertList, 1000);
        return genTableColumnDtos;
    }

    private List<GenTableColumnDto> updateList(List<GenTableColumnDto> genTableColumnDtos) {
        if (CollectionUtils.isEmpty(genTableColumnDtos)) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.INTERNAL_SERVER_ERROR, "批量更新时，参数不能为空");
        }
        for (GenTableColumnDto genTableColumnDto : genTableColumnDtos) {
            if (StringUtils.isBlank(genTableColumnDto.getColumnId())) {
                throw ExceptionFactory.createBaseException(BaseExceptionEnum.INTERNAL_SERVER_ERROR, "批量更新时，主键不能为空");
            }
        }
        List<GenTableColumn> genTableColumnList = BeanMapper.mapList(genTableColumnDtos, GenTableColumnDto.class, GenTableColumn.class);
        genTableColumnMapper.updateById(genTableColumnList, 1000);
        return genTableColumnDtos;
    }

    @Transactional(rollbackFor = Exception.class)
    public int updateById(GenTableColumnDto genTableColumnDto) {
        if (StringUtils.isBlank(genTableColumnDto.getColumnId())) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.INTERNAL_SERVER_ERROR, "更新时，主键不能为空");
        }
        GenTableColumn entity = BeanMapper.map(genTableColumnDto, GenTableColumn.class);
        return genTableColumnMapper.updateById(entity);
    }

    @Transactional(rollbackFor = Exception.class)
    public int trueDeleteById(String id) {
        return genTableColumnMapper.deleteById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    public int deleteById(GenTableColumnDto genTableColumnDto) {
        genTableColumnDto.setDelFlag(BaseConstant.YES);
        return updateById(genTableColumnDto);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteByPrimaryKeys(List<String> ids) {
        List<GenTableColumnDto> genTableColumnDtos = new ArrayList<>();
        for (String id : ids) {
            GenTableColumnDto genTableColumnDto = new GenTableColumnDto();
            genTableColumnDto.setColumnId(id);
            genTableColumnDto.setDelFlag(BaseConstant.YES);
            genTableColumnDtos.add(genTableColumnDto);
        }
        updateList(genTableColumnDtos);
    }

    @Override
    public List<GenTableColumn> selectDbTableColumnsByName(String tableName) {
        return genTableColumnMapper.selectDbTableColumnsByName(tableName);
    }

    @Override
    public List<GenTableColumnDto> queryByTableId(String tableId) {
        if (!StringUtils.isNotBlank(tableId)) {
            return new ArrayList<>();
        }
        QueryWrapper<GenTableColumn> wrapper = new QueryWrapper<>();
        wrapper.eq("table_id", tableId);
        wrapper.eq("del_flag", BaseConstant.NO);
        wrapper.orderByAsc("sort");
        List<GenTableColumn> genTableColumns = genTableColumnMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(genTableColumns)) {
            return new ArrayList<>();
        }
        return BeanMapper.mapList(genTableColumns, GenTableColumn.class, GenTableColumnDto.class);
    }

    @Override
    public void batchTrueDeleteByTableIds(List<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return;
        }
        QueryWrapper<GenTableColumn> genTableColumnQueryWrapper = new QueryWrapper<>();
        genTableColumnQueryWrapper.in("table_id", ids);
        genTableColumnMapper.delete(genTableColumnQueryWrapper);
    }

    /**
     * 标记子表的外键字段
     * 将tableId对应的主表的外键字段标记为子表的外键字段
     *
     * @param tableId
     * @param subTableFkName
     */
    @Override
    public void markFkInSubTable(String tableId, String subTableFkName) {
        List<GenTableColumnDto> genTableColumnDtos = queryByTableId(tableId);
        if (CollectionUtils.isEmpty(genTableColumnDtos)) {
            return;
        }
        GenTableColumnDto genTableColumnDto = genTableColumnDtos.stream()
                .filter(dto -> dto.getColumnName().equals(subTableFkName))
                .toList().get(0);
        genTableColumnDto.setIsFk(BaseConstant.YES);
        modify(genTableColumnDto);
    }
}
